1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| def make_onion(f, g): """Return a function can_reach(x, y, limit) that returns whether some call expression containing only f, g, and x with up to limit calls will give the result y.
>>> up = lambda x: x + 1 >>> double = lambda y: y * 2 >>> can_reach = make_onion(up, double) >>> can_reach(5, 25, 4) # 25 = up(double(double(up(5)))) True >>> can_reach(5, 25, 3) # Not possible False >>> can_reach(1, 1, 0) # 1 = 1 True >>> add_ing = lambda x: x + "ing" >>> add_end = lambda y: y + "end" >>> can_reach_string = make_onion(add_ing, add_end) >>> can_reach_string("cry", "crying", 1) # "crying" = add_ing("cry") True >>> can_reach_string("un", "unending", 3) # "unending" = add_ing(add_end("un")) True >>> can_reach_string("peach", "folding", 4) # Not possible False """ def can_reach(x, y, limit): if limit < 0: return False elif x == y: return True else: return can_reach(f(x), y, limit - 1) or can_reach(g(x), y, limit - 1) return can_reach
|